﻿/******************************************************************
 *Company: http://www.xiaomutech.com/
 *fileName : qhttpdownload.cpp --- QHttpDownload
 *Auth       : yhni (QQ:393320854)
 *Create    : 2022/9/15
 *Description   :
 *Histroy:
 *<Auth>    <Date>        <Ver>        <Content>
 *         2022/9/15
 *******************************************************************/
#include "qhttpdownload.h"

#include <QApplication>
#include <QNetworkRequest>
#include <QDebug>
#include <QTimer>
#include <QEventLoop>

#include <QJsonDocument>
#include <QJsonObject>

QHttpDownload::QHttpDownload(QObject *parent) : QObject(parent)
{
    m_http = new QNetworkAccessManager(this);
    m_isDownload  = false;
}

QHttpDownload::~QHttpDownload()
{
    m_http->deleteLater();
}

void QHttpDownload::download(const QString &_url, const QString &_fileName, const QString &_path)
{
    DownloadItem item(_url, _fileName, _path);
    m_downTask.push_back(item);
    startTask();
}

bool QHttpDownload::checkAppVersion(const QString &_appName, const quint32 &_appVer, QString &_info)
{
    QString strUrl = "http://106.15.178.227:11086/cv/" + _appName;
    QString strVersion = "0.0.0.1";

    QNetworkAccessManager manager;
    QNetworkRequest request;
    request.setUrl(QUrl(strUrl));

    QNetworkReply *pReply = manager.get(request);
    QEventLoop loop;
    connect(pReply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();
    QByteArray byData = pReply->readAll();
    QJsonDocument jsonDoc = QJsonDocument::fromJson(byData);
    QJsonObject jsonObj = jsonDoc.object();
    if (!jsonObj.isEmpty())
    {
        strVersion = jsonObj.value("verNum").toString();
        _info = jsonObj.value("verInfo").toString();
    }
    pReply->deleteLater();

    quint32 appVer = 0x00;
    QStringList versions = strVersion.split(".");
    if (4 == versions.size())
    {
        for (int i = 0; i < 4; i++)
        {
            int _value = versions.at(i).toInt();
            appVer |= (_value << (3 - i) * 8);
        }
    }

    return (appVer > _appVer);
}

void QHttpDownload::sltReadyRead()
{
    if (m_file.isOpen())
    {
        m_file.write(m_reply->readAll());
    }
}

void QHttpDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    qDebug() << "downloading: " << (bytesReceived * 100 / bytesTotal) << bytesReceived << bytesTotal << m_file.fileName();
}

void QHttpDownload::sltFinished()
{
    if (m_file.isOpen())
    {
        qDebug() << "download finished" << m_file.fileName();
        m_file.close();
        emit finished(m_file.fileName());
    }

    m_downTask.removeFirst();
    m_isDownload = false;
    QTimer::singleShot(1000, this, &QHttpDownload::startTask);
}

void QHttpDownload::startTask()
{
    if (m_isDownload) return;
    if (m_downTask.isEmpty()) {
        qDebug() << "All download finished";
        return;
    }

    if (m_file.isOpen())
    {
        m_file.close();
    }

    DownloadItem item = m_downTask.first();
    QNetworkRequest request;
    request.setUrl(item.url());
    m_file.setFileName(item.filePath());
    if (!m_file.open(QIODevice::ReadWrite))
    {
        qDebug() << "file open failed" << m_file.fileName();
        return;
    }

    m_isDownload = true;
    m_reply = m_http->get(request);
    connect(m_reply, &QNetworkReply::readyRead, this, &QHttpDownload::sltReadyRead);
    connect(m_reply, &QNetworkReply::finished, this, &QHttpDownload::sltFinished);
    connect(m_reply, &QNetworkReply::downloadProgress, this, &QHttpDownload::downloadProgress);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
DownloadItem::DownloadItem(const QString &_url, const QString &_name, const QString &_path) :
    m_url(_url), m_name(_name), m_path(_path)
{
}

QString DownloadItem::url() const
{
    return m_url;
}

void DownloadItem::setUrl(const QString &url)
{
    m_url = url;
}

QString DownloadItem::name() const
{
    return m_name;
}

void DownloadItem::setName(const QString &name)
{
    m_name = name;
}

QString DownloadItem::path() const
{
    return m_path;
}

void DownloadItem::setPath(const QString &path)
{
    m_path = path;
}

QString DownloadItem::filePath() const
{
    QString strFilePath = qApp->applicationDirPath() + "/" + m_path + "/" + m_name;
    return strFilePath;
}

